<template>
  <a-modal
    :width="650"
    :ok-loading="submitDataScopeLoading"
    v-model:visible="dialog.visible"
    :title="dialog.title"
    draggable
    @cancel="cancel"
    @ok="submitForm"
  >
    <a-spin :loading="loading" dot>
      <a-form ref="roleFormRef" :model="form" :style="{ width: '610px' }" layout="vertical">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item asterisk-position="end" field="roleName" label="角色名称" required validate-trigger="blur">
              <a-input disabled v-model.trim="form.roleName" allow-clear placeholder="请输入角色名称" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              asterisk-position="end"
              field="roleKey"
              label="权限字符"
              required
              tooltip="控制器中定义的权限字符,如:@SaCheckRole('admin')"
              validate-trigger="blur"
            >
              <a-input disabled v-model.trim="form.roleKey" allow-clear placeholder="请输入权限字符" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="16">
          <a-col :span="24">
            <a-form-item asterisk-position="end" field="roleStatus" label="菜单权限" validate-trigger="blur">
              <a-tree
                v-if="menuOptions.length"
                ref="menuRef"
                v-model:checked-keys="checkedKeys"
                :check-strictly="!form.menuCheckStrictly"
                :data="menuOptions"
                :field-names="{
                  key: 'id',
                  title: 'label',
                  children: 'children'
                }"
                checkable
                class="tree-border"
                show-line
              />
              <a-empty v-else class="tree-border" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-spin>
  </a-modal>
</template>

<script setup lang="ts">
import { roleMenuTreeSelect } from "@/api/system/menu";
import { MenuTreeOption, RoleMenuTree } from "@/api/system/menu/types";
import { getRole, updateRole } from "@/api/system/role";
const roleFormRef = ref();
const submitDataScopeLoading = ref(false);
const menuOptions = ref<MenuTreeOption[]>([]);
const checkedKeys = ref([]);
const menuRef = ref<ArcoTreeInstance>();
const dialog = reactive<DialogOption>({
  visible: false,
  title: ""
});
const loading = ref(false);
const form = ref({ roleName: undefined, roleKey: undefined, menuCheckStrictly: true, roleSort: 0, menuIds: [] });

/**
 * 展示表单
 * @param roleId 角色ID
 */
const show = async (roleId: number | string) => {
  dialog.title = "菜单权限";
  dialog.visible = true;
  loading.value = true;
  try {
    const { data } = await getRole(roleId);
    const res = await getRoleMenuTreeSelect(roleId);
    menuRef.value?.internalSetCheckedKeys(res.checkedKeys);
    Object.assign(form.value, data);
    form.value.roleSort = Number(form.value.roleSort);
  } finally {
    loading.value = false;
  }
};

/** 根据角色ID查询菜单树结构 */
const getRoleMenuTreeSelect = (roleId: string | number) => {
  return roleMenuTreeSelect(roleId).then((res): RoleMenuTree => {
    menuOptions.value = res.data.menus;
    return res.data;
  });
};

/** 取消按钮 */
const cancel = () => {
  reset();
  dialog.visible = false;
};

/** 重置新增的表单以及其他数据  */
const reset = () => {
  menuRef.value?.internalSetCheckedKeys([]);
  roleFormRef.value?.resetFields();
};

/** 提交按钮 */
const submitForm = async () => {
  submitDataScopeLoading.value = true;
  try {
    form.value.menuIds = getMenuAllCheckedKeys();
    await updateRole(form.value);
    dialog.visible = false;
  } finally {
    submitDataScopeLoading.value = false;
  }
};

/** 所有菜单节点数据 */
const getMenuAllCheckedKeys = (): any => {
  // 目前被选中的菜单节点
  let checkedKeys = menuRef.value?.checkedKeys;
  // 半选中的菜单节点
  let halfCheckedKeys = menuRef.value?.halfCheckedKeys;
  if (halfCheckedKeys) {
    checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys);
  }
  return checkedKeys;
};
defineExpose({
  show
});
</script>
<style lang="less" scoped>
.tree-border {
  border: 1px solid #e5e6e7;
  margin-top: 5px;
  border-radius: 4px;
  width: 100%;
  height: 150px;
  overflow-y: scroll;
}
</style>
